`timescale 1ns / 1ps 
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 2022/03/02 20:22:16
// Design Name:
// Module Name: vga_driver
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////


module vga_driver(clk,
                  oclk,
                  resetb,
                  vga_clk,
                  vga_dat,
                  vga_blk_n,
                  vga_sync_n,
                  vga_hs,
                  vga_vs,
                  rd,
                  rdat,
                  hcnt,
                  vcnt,
                  x_max,
                  x_min,
                  y_max,
                  y_min

                 );
parameter IMG_H = 800;
parameter IMG_V = 600;
parameter H_SYNC = 11'd128;
parameter H_BACK = 11'd88;
parameter H_DISP = 11'd800;
parameter H_FRONT = 11'd40;
parameter H_TOTAL = H_SYNC + H_BACK + H_DISP + H_FRONT;
parameter V_SYNC = 10'd4;
parameter V_BACK = 10'd23;
parameter V_DISP = 10'd600;
parameter V_FRONT = 10'd1;
parameter V_TOTAL = V_SYNC + V_BACK + V_DISP + V_FRONT;
input clk;
input oclk;
input resetb;
input [10: 0] x_max;
input [10: 0] x_min;
input [10: 0] y_max;
input [10: 0] y_min;
output vga_clk;
output [23: 0] vga_dat;
output vga_blk_n;
output vga_sync_n;
output vga_hs;
output vga_vs;
output rd;
input [15: 0] rdat;
output [10: 0] hcnt;
output [10: 0] vcnt;
parameter ck2q = 1;
reg [10: 0] hcnt;
wire hcnt_tc = (hcnt == H_TOTAL - 1);
always@(posedge clk or negedge resetb)
	begin
		if (!resetb)
			hcnt <= #ck2q 0;
		else if (hcnt_tc)
			hcnt <= #ck2q 0;
		else
			hcnt <= #ck2q hcnt + 1'b1;
	end
wire vga_hs = ~(hcnt < H_SYNC);
reg [10: 0] vcnt;
wire vcnt_tc = (vcnt == V_TOTAL - 1);
always@(posedge clk or negedge resetb)
	begin
		if (!resetb)
			vcnt <= #ck2q 0;
		else if (hcnt_tc)
			begin
				if (vcnt_tc)
					vcnt <= #ck2q 0;
				else
					vcnt <= #ck2q vcnt + 1'b1;
			end
	end
wire vga_vs = ~(vcnt < V_SYNC);
assign vga_sync_n = 1'b1;
assign vga_blk_n = vga_vs & vga_hs;
assign vga_clk = oclk;
reg [3: 0] cnt_fps;
reg rd_en;
always@(posedge clk or negedge resetb)
	begin
		if (!resetb)
			begin
				cnt_fps <= #ck2q 0;
				rd_en <= #ck2q 0;
			end
		else if (cnt_fps == 4'd9)
			rd_en <= #ck2q 1'b1;
		else
			cnt_fps <= #ck2q cnt_fps + 1'b1;
	end
wire rd = rd_en & ((hcnt >= H_SYNC + H_BACK - 1 ) & (hcnt < H_SYNC + H_BACK + IMG_H - 1 )
                   & ( vcnt >= V_SYNC + V_BACK ) & (vcnt < V_SYNC + V_BACK + IMG_V ));
wire [23: 0] rdat_cb;
colorbar u_colorbar(
             .clk ( clk ),
             .resetb ( resetb ),
             .rd ( rd ),
             .rdat ( rdat_cb )
         );
reg rd_d0;
always@(posedge clk or negedge resetb)
	begin
		if (!resetb)
			rd_d0 <= #ck2q 0;
		else
			rd_d0 <= #ck2q rd;
	end
wire [23: 0] rdat_w = {rdat[15: 11], rdat[13: 11], rdat[10: 5], rdat[6: 5], rdat[4: 0], rdat[2: 0]};
reg [23: 0] vga_dat;
always@( * )
	begin
		if (rd_d0)
			begin
				if ((((hcnt == x_min) | (hcnt == x_min + 11'd1) |
				        (hcnt == x_max) | (hcnt == x_max + 11'd1)) & ((vcnt >= y_min) & (vcnt <= y_max)))
				        | (((vcnt == y_min) | (vcnt == y_min + 11'd1) |
				            (vcnt == y_max) | (vcnt == y_max + 11'd1)) & ((hcnt >= x_min) & (hcnt <= x_max))))
					vga_dat = 24'hff00ff;
				else
					vga_dat = rdat_w;
			end
		else
			vga_dat = 24'h000000;
	end
//assign vga_dat = rd_d0 ? rdat : 24'h000000;
endmodule
